﻿using Microsoft.EntityFrameworkCore;
using Mojito.Data.Entities;
using Mojito.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mojito.Services
{
    public class DirectoriesService : AppServiceBase
    {
        /// <summary>
        ///  获取工作区
        /// </summary>
        /// <returns></returns>
        public async Task<IList<RequestDirectory>> GetWorkspace()
        {
            var list = await Context.RequestDirectory
                .Where(d => d.ParentId == null)
                .OrderBy(d => d.CreateUserDate)
                .ToListAsync();
            return list;
        }

        /// <summary>
        ///  获取我的工作区
        ///  我创建的工作区 & 别人分享给我的工作区
        /// </summary>
        /// <returns></returns>
        public async Task<IList<WorkspaceOutput>> GetMyWorkspace(string userId)
        {
            var workspaceList = await Context.RequestDirectory
                .Where(d => d.ParentId == null)
                .OrderBy(d => d.CreateUserDate)
                .ToListAsync();

            var myList = workspaceList
                .Where(d => d.CreateUserId == userId)
                .Select(s => new WorkspaceOutput
                {
                    Id = s.Id,
                    Name = s.Name,
                    IsShare = false
                })
                .ToList();

            var shareList = Context.RequestShare
                .Where(d => d.AccountId == userId)
                .ToList();

            var s2 = shareList
                .Join(
                    workspaceList,
                    s => s.DirectoryId,
                    w => w.Id,
                    (s, w) => w)
                .ToList();

            var s3 = s2.Select(d => new WorkspaceOutput
            {
                Id = d.Id,
                Name = d.Name,
                IsShare = true,
                OwnerId = d.CreateUserId
            });

            return myList.Concat(s3).ToList();
        }

        /// <summary>
        ///  更新工作区
        /// </summary>
        /// <returns>新工作区id</returns>
        public async Task<WorkspaceOutput> SaveWorkspace(string userId, DirectoryInput input)
        {
            if (await Context.RequestDirectory.AnyAsync(d => d.Id != input.Id && d.Name == input.Name))
            {
                throw new ApplicationException("已经存在相同的工作区名字");
            }

            var directory = await Context.FindAsync<RequestDirectory>(input.Id);
            if(directory == null)
            {
                directory = new RequestDirectory
                {
                    Id = Guid.NewGuid().ToString("N"),
                    CreateUserId = userId,
                    CreateUserDate = DateTime.Now.ToString("yyyyMMddHHmmss"),
                    Name = input.Name,
                    ParentId = null
                }; 
                await Context.AddAsync(directory);
            }
            else
            {
                directory.Name = input.Name;
                Context.Update(directory);
            }
            await Context.SaveChangesAsync();
            return new WorkspaceOutput
            {
                Id = directory.Id,
                Name = directory.Name
            };
        }


        /// <summary>
        ///  添加工作区
        /// </summary>
        /// <returns>新工作区id</returns>
        public async Task<int> DestroyWorkspace(string Id)
        {
            var directory = await Context.FindAsync<RequestDirectory>(Id);
            if (directory == null)
            {
                throw new ApplicationException("找不到该工作区");
            }
            else
            {
                if (await Context.RequestDirectory.AnyAsync(d => d.ParentId == Id))
                    throw new ApplicationException("该目录下还有子目录, 无法删除");

                Context.Remove(directory);
            }
            return await Context.SaveChangesAsync();
        }


        /// <summary>
        ///  获取子目录树
        /// </summary>
        /// <param name="workDirId">工作区目录</param>
        /// <returns></returns>
        public async Task<IList<DirectoriesOutput>> GetDirectories(string workDirId)
        {
            var folders = await Context
                .RequestDirectory
                .ToListAsync();

            var requests = await Context
                .Request
                .ToListAsync();

            return GetTree(folders, requests, workDirId);
        }

        /// <summary>
        ///  添加子目录
        /// </summary>
        /// <returns></returns>
        public async Task<string> SaveDirectory(DirectoriesOutput input)
        {
            var directory = await Context.FindAsync<RequestDirectory>(input.Id);
            if(directory == null)
            {
                directory = new RequestDirectory
                {
                    Id = Guid.NewGuid().ToString("N"),
                    CreateUserDate = DateTime.Now.ToString("yyyyMMddHHmmss"),
                    Name = input.Name,
                    ParentId = input.ParentId
                };
                await Context.AddAsync(directory);
            }
            else
            {
                directory.Name = input.Name;
                Context.Update(directory);
            }
            await Context.SaveChangesAsync();
            return directory.Id;
        }


        /// <summary>
        ///  删除目录
        /// </summary>
        /// <returns>新工作区id</returns>
        public async Task<int> DestroyDirectory(string Id)
        {
            var directory = await Context.FindAsync<RequestDirectory>(Id);
            if (directory == null)
                throw new ApplicationException("找不到该工作区");
            
            if(await Context.RequestDirectory.AnyAsync(d => d.ParentId == Id))
                throw new ApplicationException("该目录下还有子目录, 无法删除");

            if (await Context.Request.AnyAsync(d => d.FolderId == Id))
                throw new ApplicationException("该目录下还有子项, 无法删除");

            //if(directory.Items != null && directory.Items.Count > 0)
            //    throw new ApplicationException("该目录下还有子文件, 无法删除");

            //if(await Context.Request.AnyAsync(d => d.FolderId == Id))
            //    throw new ApplicationException("该目录下还有子项, 无法删除");

            Context.Remove(directory);
            return await Context.SaveChangesAsync();
        }


        /// <summary>
        ///  TO DO 预加载, 利用深搜直接获得数据
        /// </summary>
        /// <param name="folders"></param>
        /// <param name="requests"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public IList<DirectoriesOutput> GetTree(IList<RequestDirectory> folders, IList<Request> requests, string parentId)
        {
            var dto = new List<DirectoriesOutput>();
            var _f = folders.Where(d => d.ParentId == parentId);
            var _r = requests.Where(d => d.FolderId == parentId);

            foreach (var folder in _f)
            {
                dto.Add(new DirectoriesOutput
                {
                    Id = folder.Id,
                    Name = folder.Name,
                    OriginalName = folder.Name,
                    ParentId = parentId,
                    Type = -1,
                    IsEditing = false,
                    Items = GetTree(folders, requests, folder.Id)
                });
            }

            foreach (var request in _r)
            {
                dto.Add(new DirectoriesOutput
                {
                    Id = request.Id,
                    Name = request.Title,
                    OriginalName = request.Title,
                    ParentId = parentId,
                    Type = (int)request.Method,
                    IsEditing = false
                });
            }

            return dto;
        }
    }
}
